package apifm

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/mqueuex"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	utilx "mall/common/utils/user"
	"mall/service/attachment/rpc/attachmentclient"
	enum "mall/service/backend/common/enum/setting"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/user/rpc/userclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type UserModifyLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserModifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserModifyLogic {
	return &UserModifyLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserModifyLogic) UserModify(
	req *types.UserModifyReq,
	headers *[]*types.Header,
) (*types.BaseMsgResp, error) {
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	//securityStatus := jwt.GetSecurityStatus(l.ctx)
	//logrus.Info(fmt.Sprintf("UserModify GetSecurityStatus : %+v ", securityStatus))
	//if securityStatus != jwt.CERTIFICATED {
	//	return nil, resultx.NewErrCode(resultx.USER_STATUS_INVALID)
	//}

	var platform string
	if req.AuthType == nil || len(strings.TrimSpace(*req.AuthType)) == 0 {
		platform = globalkey.UserAuthTypeWechatMini
	} else {
		platform = *req.AuthType
	}
	platformId := utilx.GetThirdPartyPlatformId(platform)
	if platformId == 0 {
		return nil, resultx.NewErrCode(resultx.USER_AUTH_MODIFY_FAILED)
	}

	newMediaMap := make(map[string]*types.TmpMediaInfo)
	var newMediaIds []string // 用于查询 attachmentRpc
	var thumbnail *uint32 = pointy.GetPointer(uint32(1))
	var newMedia []*userclient.TmpUserMediaInfo
	var newAttachmentIds []string // 用于主动通知 attachmentRpc
	if len(req.NewMedia) > 0 {
		for _, v := range req.NewMedia {
			if v.Id != nil && len(*v.Id) > 0 {
				if _, ok := newMediaMap[*v.Id]; !ok { // 忽略重复id
					newMediaMap[*v.Id] = v
					newMediaIds = append(newMediaIds, *v.Id)
				}
			} else { // 第三方图片
				newMedia = append(newMedia, &userclient.TmpUserMediaInfo{
					Uid:       v.Uid,
					Thumbnail: thumbnail,
					Order:     v.Order,
					Url:       v.Url,
					Name:      v.Name,
					AltText:   v.AltText,
					MetaData:  v.MetaData,
				})
			}
		}
	}

	// 根据 newMediaIds 查询 attachments 记录到 user_attachment_relationship
	if len(newMediaIds) > 0 {
		res, err := l.svcCtx.AttachmentRpc.BackendGetFileList(l.ctx, &attachmentclient.FileListReq{
			Ids: pointy.GetPointer(strings.Join(newMediaIds, ",")),
		})
		if err != nil {
			return nil, err
		}

		if len(res.List) > 0 {
			for _, v := range res.List {
				if v.Id != nil && len(*v.Id) > 0 {
					if item, ok := newMediaMap[*v.Id]; ok {
						var url string
						if v.Url != nil && len(*v.Url) > 0 {
							url = fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.StaticUrl, *v.Url)
						}
						if len(url) == 0 && v.Path != nil && len(*v.Path) > 0 {
							url = fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.ProxyUrl, *v.Path)
						}
						newMedia = append(newMedia, &userclient.TmpUserMediaInfo{
							Uid:       item.Uid,
							Id:        v.Id,
							Thumbnail: thumbnail,
							Order:     item.Order,
							Uri:       item.Url,
							Url:       pointy.GetPointer(url),
							Name:      item.Name,
							AltText:   item.AltText,
							MetaData:  item.MetaData,
						})
						newAttachmentIds = append(newAttachmentIds, *v.Id)
					}
				}
			}
		}
	}

	_, err := l.svcCtx.UserRpc.UpdateUserAuthInfo(l.ctx, &userclient.TmpUserAuthInfo{
		UserId:         pointy.GetPointer(userId),
		PlatformId:     pointy.GetPointer(platformId),
		Nickname:       req.Nickname,
		Avatar:         req.Avatar,
		Gender:         req.Gender,
		Birthday:       req.Birthday,
		BirthdayHidden: req.BirthdayHidden,
		NewMedia:       newMedia,
	})
	if err != nil {
		return nil, err
	}

	if len(newAttachmentIds) > 0 {
		_, err = l.svcCtx.AttachmentRpc.CreateFileLog(l.ctx, &attachmentclient.CreateFileLogReq{
			FileIds:    newAttachmentIds,
			UserId:     pointy.GetPointer(strconv.FormatInt(int64(userId), 10)),
			Put:        pointy.GetPointer(uint32(1)),
			ObjectId:   pointy.GetPointer(userId),
			ObjectType: pointy.GetPointer(uint32(globalkey.AttachmentLogTypeUserAvatar)),
		})
		if err != nil {
			logx.Errorw("UserModify CreateFileLog err", logx.Field("detail", err.Error()))
		}
	}

	if req.WithTask != nil && *req.WithTask > 0 {
		err = l.distributePoints(userId)
		if err != nil {
			logx.Errorw("UserModify distributePoints err", logx.Field("detail", err.Error()))
		}
	}

	return &types.BaseMsgResp{}, nil
}

func (l *UserModifyLogic) distributePoints(uid uint64) error {
	m := mqueuex.DistributePointsMessage{
		UserId: pointy.GetPointer(uid),
		Task:   pointy.GetPointer(enum.MemberTaskFulfillProfile),
	}
	body, err := json.Marshal(m)
	if err != nil {
		logx.Errorw("UserModify distributePoints json.Marshal err", logx.Field("detail", err.Error()))
		return err
	}

	return l.svcCtx.KqDistributePointsClient.Push(string(body))
}
